const mongoose = require('mongoose')
const { ObjectId } = mongoose.Types
const { Shop, Comment, Users, Order, Category } = require('../../schema')
const { sales, classify, userBuy } = require('../../figures')

mongoose.connect('mongodb://127.0.0.1:27017/sportswear').then()

const shopCollection = mongoose.model('shop', Shop)
const commentCollection = mongoose.model('comments', Comment)
const userCollection = mongoose.model('users', Users)
const orderCollection = mongoose.model('order', Order)
const categoryCollection = mongoose.model('category', Category)

function querySaleTotal () {
    return new Promise(resolve => {
        shopCollection.aggregate([{
            $group: {
                _id: '$category',
                total: {
                    $sum: '$sales'
                }
            }
        }]).then(res => {
            resolve(res.reduce(function (count, item) {
                return count + item.total
            }, 0))
        })
    })
}

function queryShopTotal () {
    return new Promise(resolve => {
        shopCollection.find({}).count().then(res => {
            resolve(res)
        })
    })
}

function queryUnloadShop () {
    return new Promise(resolve => {
        shopCollection.find({ issale: false }).count(1).then(res => {
            resolve(res)
        })
    })
}

function queryUserTotal () {
    return new Promise(resolve => {
        userCollection.find({}).count().then(res => {
            resolve(res)
        })
    })
}

function queryGoodComments () {
    return new Promise(resolve => {
        commentCollection.find({ star: { $gte: 4 } }).count(1).then(good => {
            commentCollection.find({}).count(1).then(total => {
                resolve(((good / total).toFixed(3) * 100).toFixed(1))
            })
        })
    })
}

function queryReturnBackUsers () {
    return new Promise(resolve => {
        orderCollection.aggregate([{
            $group: {
                _id: '$userid',
                products: {
                    $push: '$proid'
                }
            }
        }]).then(res => {
            // console.log(res)
            resolve(filterRepeatCustomers(res).length)
        })
    })
}

async function figureForSales (timeStamp) {
    const now = zero(new Date())
    const current = getDay(now)

    let xAxis = []
    let yAxis = []
    let query = []
    let queryAll = []
    let _date = null
    for (let pre = 0; pre < 7; pre++) {
        _date = dateStep(now, -pre)
        xAxis.unshift(dateFormat(_date))
        query.unshift({
            min: new Date(_date.getTime() + 8 * 60 * 60 * 1000),
            max: new Date(_date.getTime() + 24 * 60 * 60 * 1000 + 8 * 60 * 60 * 1000)
        })
    }
    query.forEach(item => {
        let qid = orderCollection.find({
            time: {
                $gte: item.min,
                $lt: item.max
            }
        }).count(1)
        queryAll.push(qid)
    })
    yAxis = await Promise.all(queryAll)
    sales.xAxis[0].data = xAxis
    sales.series[0].data = yAxis
    return sales
}

async function figureForClassify () {
    const { categoryList } = await categoryCollection.findOne({})
    const value = await shopCollection.aggregate([{
        $group: {
            _id: '$category',
            total: {
                $sum: '$sales'
            }
        }
    }])
    const data = []
    const dataAxis = []
    for (let i = 0; i < categoryList.length; i++) {
        let search = Array.from(value).find(item => item._id === categoryList[i])
        search ? data.push(search.total) : null
        dataAxis.push(categoryList[i])
    }
    classify.series[0].data = data
    classify.xAxis.data = dataAxis
    return classify
}

async function figureForUserBuy (userid) {
    return new Promise(resolve => {
        try {
            orderCollection.aggregate([{
                $lookup: {
                    from: 'shops',
                    localField: 'proid',
                    foreignField: 'proid',
                    as: 'buy'
                }
            }, {
                $match: {
                    userid: ObjectId(userid),
                    state: {
                        $ne: 4
                    }
                }
            }]).then(res => {
                if (formatData(res).length) {
                    userBuy.series[0].data = formatData(res)
                } else {
                    userBuy.series[0].data = [{ name: '从未购买', value: 1 }]
                }
                resolve(userBuy)
            })
        } catch (e) {
            userBuy.series[0].data = [{ name: '从未购买', value: 1 }]
            resolve(userBuy)
        }
    })
}

function formatData (arr) {
    const hashMap = {}
    const result = []
    arr.forEach(item => {
        let clsid = item.buy[0] && item.buy[0].category || '其他'
        if (!hashMap[clsid]) {
            hashMap[clsid] = 0
        }
        hashMap[clsid] += item.count
    })
    for (let key in hashMap) {
        result.push({ name: key, value: hashMap[key] })
    }
    return result
}

function filterRepeatCustomers (data) {
    return data.filter(item => {
        const origin = Array.from(item.products.map(item => item.toString()))
        const pure = Array.from(new Set(item.products.map(item => item.toString())))
        return pure.length !== origin.length
    })
}

function zero (date) {
    date.setHours(0)
    date.setMinutes(0)
    date.setSeconds(0)
    return date
}

function dateFormat (date) {
    return (date.getMonth() + 1) + '月' + date.getDate() + '日'
}

function dateStep (date, step) {
    let _date = new Date(date.getTime())
    _date.setDate(date.getDate() + step)
    return _date
}

function getDay (date) {
    let day = date.getDay()
    if (day === 0) {
        day = 6
    } else {
        day = day - 1
    }
    return day
}

module.exports = {
    queryShopTotal,
    queryUserTotal,
    queryGoodComments,
    queryReturnBackUsers,
    queryUnloadShop,
    querySaleTotal,
    figureForSales,
    figureForClassify,
    figureForUserBuy
}
